feat(core): session-scoped dock UI state — restore open/selected dock, tab, and scroll across reloads - #527
Open
dvcolomban wants to merge 3 commits into
Open
Conversation
…, tab, and scroll across reloads Splits the dock panel's persisted state in two: config (geometry/position/ mode/inactiveTimeout) stays in localStorage (vite-devtools-dock-state, cross-tab), while *state* (open, selected dock, active tab, scroll position) moves to sessionStorage (vite-devtools-dock-session, per-tab) — a full page reload no longer leaves the panel open-but-empty or resets scroll/tab. - createDocksContext (context.ts) now backs open + selectedId with a single useSessionStorage store, merged with the geometry-only panelStore into the same DockPanelStorage shape every dock component already reads/writes through context.panel.store — only open's backing store changes. - A restored selectedId is validated once at boot (once dock entries have actually loaded) against being a real selectable leaf — not a group, a subTabs anchor, or a stale id — clearing it without routing through switchEntry (which would force the panel back open). Past that one-time check, switchEntry may legitimately land on a group/anchor id itself (e.g. a subTabs anchor with no live member yet) — this doesn't re-litigate that. - DockEmbedded now mirrors DockStandalone's own auto-select-first-entry boot guard, gated on the panel actually being open. - ViewJsonRender provides its dock entry id for descendants to inject, and restores/persists its own scroll position per dock, debounced. - New useUncontrolledValue composable: session-persisted fallback for a json-render element's own uncontrolled value, keyed by the injected dock id plus a signature of the element's static shape (works around FlatElement.key not being forwarded to registry components). Tabs now uses it instead of its hand-rolled ref; Select/TextInput/Switch — until now inert while unbound — get it too. Two behavior changes ship with this, both intentional: - Opening the docks in one tab no longer auto-opens them in another tab of the same page (open moved from localStorage to sessionStorage). - The very first load after this ships, the panel starts closed even if a user's old vite-devtools-dock-state said open: true — that key's open is simply never read again. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
…ionStorage split Folds selectedId into the existing localStorage-backed panelStore instead of a separate sessionStorage-scoped store: it's a browser-local singleton exactly like open/mode/position, so it belongs in the same object and gets mirrored for free once that object is shared over RPC. Only the active spec tab and scroll position stay genuinely per-tab (still sessionStorage, via each ViewJsonRender's own independent key) since nothing server-side needs them and syncing them across tabs would be unwanted UX.
@vitejs/devtools
@vitejs/devtools-kit
@vitejs/devtools-oxc
@vitejs/devtools-rolldown
@vitejs/devtools-vite
@vitejs/devtools-vitest
commit: |
dvcolomban
marked this pull request as ready for review
August 10, 2026 15:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Reloading the page (dev-server restart, an HMR full-reload, etc.) always dropped back to whatever dock is open by default, which gets annoying mid-debugging.
What changed
ViewJsonRenderdock —sessionStorage, keyed per dock and tab, since nothing server-side needs to see these and syncing them across tabs would be unwanted UX.selectedId, folded into the existing localStorage-backedpanelStorealongsideopen/mode/position/geometry, rather than a second store, since it's a browser-local singleton exactly like those already are.Linked Issues
Additional context
selectedIdliving in the same object asopenmeans it inherits #525's shared-state mirror for free, if that one lands — no separate wiring needed there.Demo
Screen.Recording.2026-08-10.at.15.38.35.mov